#pragma once

#include "Singleton.h"
#include "GameServerSession.h"

class GameServerMgr : public Singleton<GameServerMgr>
{
public:
	GameServerMgr();
	virtual ~GameServerMgr();

	bool RegisterGameServer(GameServerSession* pSession);
	void RemoveGameServer(GameServerSession* pSession);

	void KickPlayer(uint32 uid, GErrorCode error);

	void SendPacket2GS(const INetPacket& pck);
	void SendPacket2GS(const INetPacket& pck, const INetPacket& data);

	void SendPacket2AllMS(const INetPacket& pck);
	void SendPacket2Instance(InstGUID instGuid, const INetPacket& pck);
	void SendPacket2Player(uint32 uid, const INetPacket& pck);

	RPCError RPCInvoke2GS(const INetPacket &pck,
		const std::function<void(INetStream&, int32, bool)> &cb = nullptr,
		AsyncTaskOwner *owner = nullptr, time_t timeout = DEF_RPC_TIMEOUT);
	void RPCReply2GS(const INetPacket &pck,
		uint64 sn, int32 err = RPCErrorNone, bool eof = true);

	RPCError RPCInvoke2Instance(InstGUID instGuid, const INetPacket& pck,
		const std::function<void(INetStream&, int32, bool)>& cb = nullptr,
		AsyncTaskOwner* owner = nullptr, time_t timeout = DEF_RPC_TIMEOUT);
	void RPCReply2MS4Instance(InstGUID instGuid, const INetPacket &pck,
		uint64 sn, int32 err = RPCErrorNone, bool eof = true);

	RPCError RPCInvoke2Player(uint32 uid, const INetPacket& pck,
		const std::function<void(INetStream&, int32, bool)>& cb = nullptr,
		AsyncTaskOwner* owner = nullptr, time_t timeout = DEF_RPC_TIMEOUT);
	void RPCReply2MS4Player(uint32 uid, const INetPacket &pck,
		uint64 sn, int32 err = RPCErrorNone, bool eof = true);

	void SetServerId(uint32 serverId) { m_serverId = serverId; }
	void SetStartServerTime(int64 time) { m_startServerTime = time; }
	uint32 GetServerId() const { return m_serverId; }
	time_t GetStartServerTime() const { return m_startServerTime; }

	GameServerSession* GetGameServerSession() const { return m_pGameServerSession; }

private:
	uint32 m_serverId;
	time_t m_startServerTime;
	GameServerSession* m_pGameServerSession;
};

#define sGameServerMgr (*GameServerMgr::instance())
